package lex.title.maxthon;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPopupMenu;
import javax.swing.JRootPane;

import org.lex.awt.GraphicsUtils;

import lex.title.MaximizeRestoreButton;
import lex.title.MenuButton;
import lex.title.ToggleButton;
import lex.title.WindowButton;
import lex.title.WindowButtonUI;
import lex.title.basic.BasicWindowTitle;
import lex.util.FvwmLayout;
import lex.util.ImageCache;
import lex.util.Utilities;

public class MaxthonWindowTitle extends BasicWindowTitle {
	private WindowButton closeButton = null;
	private WindowButton minimizeButton = null;
	private MaximizeRestoreButton maximizeRestoreButton = null;
	private MenuButton menuButton = null;
	private ToggleButton pinButton = null;
	private JPopupMenu menu = null;
	// ======================================================
	private Color activeColor = Color.black;
	private Color inactiveColor = new Color(115, 115, 115);

	public MaxthonWindowTitle(JRootPane rootPane) {
		super(rootPane);
		if (true == this.isNoneDecoration())
			return;
		// ===================================
		this.setLayout(new FvwmLayout(0, 5, 0));
		this.add("right top 0", this.getCloseButton());
		this.add("left center 0", this.getMenuButton());
		if (true == isFrame()) {
			this.add("right top 1", this.getMaximizeRestoreButton());
			this.add("top right 2", this.getMinimizeButton());
		}
		this.add("right top 3", this.getPinButton());
	}

	protected ToggleButton getPinButton() {
		if (null == pinButton) {
			ImageCache ic = ImageCache.getInstance();
			Image img1 = ic.getMaxthonImage("details.png");
			Image img2 = ic.getMaxthonImage("details-rollover.png");
			pinButton = new ToggleButton(img1, img2);
			pinButton.setAction(this.getStayOnTopAction());
			Object v = getStayOnTopAction().getValue(Action.SELECTED_KEY);
			if (true == Boolean.valueOf(String.valueOf(v)).booleanValue())
				pinButton.setImageIndex(1);
		}
		return pinButton;
	}

	protected WindowButton getCloseButton() {
		if (null == closeButton) {
			ImageCache ic = ImageCache.getInstance();
			WindowButtonUI ui = new WindowButtonUI(ic.getMaxthonImage("close.png"), ic.getMaxthonImage("close-rollover.png"));
			closeButton = new WindowButton(ui, this.getCloseAction());
		}
		return closeButton;
	}

	protected WindowButton getMinimizeButton() {
		if (null == minimizeButton) {
			ImageCache ic = ImageCache.getInstance();
			WindowButtonUI ui = new WindowButtonUI(ic.getMaxthonImage("minimize.png"), ic.getMaxthonImage("minimize-rollover.png"));
			minimizeButton = new WindowButton(ui, getMinimizeAction());
		}
		return minimizeButton;
	}

	protected MaximizeRestoreButton getMaximizeRestoreButton() {
		if (null == this.maximizeRestoreButton) {
			ImageCache ic = ImageCache.getInstance();
			WindowButtonUI maximizeUI = new WindowButtonUI(ic.getMaxthonImage("maximize.png"), ic.getMaxthonImage("maximize-rollover.png"));
			WindowButtonUI restoreUI = new WindowButtonUI(ic.getMaxthonImage("restore.png"), ic.getMaxthonImage("restore-rollover.png"));
			maximizeRestoreButton = new MaximizeRestoreButton(maximizeUI, restoreUI);
			maximizeRestoreButton.setActions(this.getMaximizeAction(), this.getRestoreAction());
		}
		return maximizeRestoreButton;
	}

	protected JButton getMenuButton() {
		if (null == this.menuButton) {
			menuButton = new MenuButton(this);
			menuButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					JComponent c = MaxthonWindowTitle.this;
					JPopupMenu p = getMenu();
					int y = c.getHeight();
					if (true == isLeftToRight())
						p.show(c, 0, y);
					else
						p.show(c, getWidth() - p.getWidth(), y);
				}
			});
		}
		return menuButton;
	}

	private JPopupMenu getMenu() {
		if (null == menu) {
			menu = new JPopupMenu();
			menu.add(this.getRestoreAction());
			menu.add(this.getMinimizeAction());
			menu.add(this.getMaximizeAction());
			menu.addSeparator();
			menu.add(this.getCloseAction());
		}
		return menu;
	}

	protected void paintComponent(Graphics g) {
		if (getFrame() != null) {
			setState(getFrame().getExtendedState());
		}
		Window window = this.getWindow();
		boolean active = true;
		if (null != window) {
			active = window.isActive();
		}
		int width = getWidth();
		int height = getHeight();
		Graphics2D g2 = (Graphics2D) g;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		// ===============================================
		drawMacBackground(g2, active, width, height);
		String titleString = getTitle();
		if (null == titleString)
			return;
		Font font = getFont();
		g.setFont(font);
		FontMetrics fm = g.getFontMetrics();
		int x = menuButton.getX() + menuButton.getWidth() + 5;
		int availTitleWidth = menuButton.getX() + menuButton.getWidth();
		if (isFrame())
			availTitleWidth = minimizeButton.getX() - availTitleWidth;
		else
			availTitleWidth = closeButton.getX() - availTitleWidth;
		titleString = Utilities.clipStringIfNecessary(fm, titleString, availTitleWidth);
		int y = GraphicsUtils.getVerticalPlacement(fm, height);
		if (active)
			g.setColor(this.activeColor);
		else
			g.setColor(this.inactiveColor);
		g.drawString(titleString, x, y);
	}

	void drawMacBackground(Graphics2D g2, boolean active, int w, int h) {
		GradientPaint grad = active ? new GradientPaint(0, 0, new Color(238, 238, 238), 0, h - 1, new Color(192, 192, 192)) : new GradientPaint(0, 0,
				new Color(230, 230, 230), 0, h - 1, new Color(202, 202, 202));
		g2.setPaint(grad);
		g2.fillRect(0, 0, w, h - 1);
		g2.setColor(new Color(198, 198, 198));
		g2.drawLine(0, 0, w - 1, 0);
		g2.setColor(Color.WHITE);
		g2.drawLine(0, 1, w - 1, 1);
		g2.setColor(new Color(147, 147, 147));
		g2.drawLine(0, h - 1, w, h - 1);
	}

	void drawMaxthonBackground(Graphics2D g2, boolean active, int w, int h) {
		GradientPaint grad = new GradientPaint(0, 0, new Color(244, 244, 241), 0, h - 1, new Color(230, 229, 225));
		g2.setPaint(grad);
		g2.fillRect(0, 0, w, h - 1);
		g2.setColor(new Color(128, 128, 128));
		g2.drawLine(0, 0, w - 1, 0);
		g2.setColor(Color.WHITE);
		g2.drawLine(0, 1, w - 1, 1);
		g2.setColor(new Color(160, 160, 160));
		g2.drawLine(0, h - 1, w, h - 1);
	}
}
